package com.metaverse.backend.web.open;

import com.alibaba.fastjson.JSONObject;
import com.metaverse.backend.domain.User;
import com.metaverse.backend.douyin.RoomDataDTO;
import com.metaverse.backend.enums.LoginType;
import com.metaverse.backend.exception.AuthenticationException;
import com.metaverse.backend.exception.BusinessException;
import com.metaverse.backend.security.JwtTokenUtil;
import com.metaverse.backend.security.JwtUser;
import com.metaverse.backend.security.JwtUserFactory;
import com.metaverse.backend.service.DouYinApiService;
import com.metaverse.backend.service.UserRegisterService;
import com.metaverse.backend.service.UserService;
import com.metaverse.backend.utils.ApplicationContextUtil;
import com.metaverse.backend.utils.BusiResult;
import io.swagger.annotations.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Api(tags="用户登录")
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/open/login")
public class OpenLoginController {

    public static final List<String> TEST_ID_LIST = Arrays.asList("111111","222222","333333");

    private final AuthenticationManager authenticationManager;
    private final JwtTokenUtil          jwtTokenUtil;


    private final UserService userService;

    private final UserRegisterService userRegisterService;

    private final DouYinApiService douYinApiService;

//    /**
//     * 普通用户登录
//     * @param username
//     * @param password
//     * @return
//     */
//    @ApiOperation("通过用户名和密码登录")
//    @PostMapping("/loginByUserPwd")
//    public BusiResult<JSONObject> loginByUserPwd(
//                                 @RequestParam("username") String username,
//                                 @RequestParam("password") String password
//                                 ) {
//        Authentication authentication = authenticate(username, password);
//        JwtUser jwtUser = (JwtUser) authentication.getPrincipal();
//
//        if(!jwtUser.getUser().isAdmin()){
//            throw new BusinessException("只允许管理员进行登录");
//        }
//
//        String token = jwtTokenUtil.generateToken(jwtUser);
//        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("token",token);
//        return BusiResult.success(jsonObject);
//    }


//
//    /**
//     * 通过授权码登录
//     * @return
//     */
//    @ApiOperation("通过用户id和房间id登录")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name="openid", value="用户唯一ID", required=true),z
//            @ApiImplicitParam(name="roomId", value="房间ID", required=true),
//    })
//    @PostMapping("/loginByCode")
    public BusiResult<JSONObject> loginByCode(@RequestParam String openid,
                                              @RequestParam String roomId,
                                              String avatar, String nickName){

        if(StringUtils.isEmpty(openid) || StringUtils.isEmpty(roomId)){
            throw new BusinessException("缺失必要的参数");
        }


        //检查是否注册
        User user;
        if(!userService.existOpenid(openid)){
            userRegisterService.registerByOpenId( openid);
            user = userService.login(openid, LoginType.REGISTER);
        }else{
            user = userService.login(openid, LoginType.JSCODE);
        }

        //更新用户信息
        if(StringUtils.isNotBlank(avatar) || StringUtils.isNotBlank((nickName))){
            user.setAvatar(avatar);
            user.setNickname(nickName);
            userService.updateData(user);
        }

        JwtUser jwtUser = JwtUserFactory.create(user);
        String token = jwtTokenUtil.generateToken(jwtUser, roomId);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("token",token);
        jsonObject.put("openid",user.getOpenid());
        jsonObject.put("userId",user.getId());
        jsonObject.put("username",user.getUsername());
        jsonObject.put("roomId", roomId);
        return BusiResult.success(jsonObject);
    }


    /**
     * 通过授权码登录
     * @return
     */
    @ApiOperation("通过授权码登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name="token", value="pc端token", required=true),
    })
    @PostMapping("/loginByToken")
    public BusiResult<JSONObject> loginByToken(@RequestParam String token){
        if(StringUtils.isBlank(token)){
            throw new BusinessException("登录token不能为空");
        }

        if (!ApplicationContextUtil.isRunProd()){
            String openidAndRoomId = null;
            if(TEST_ID_LIST.contains(token)){
                openidAndRoomId = token;
            }else{
                //分配
                openidAndRoomId = "999999";
            }

            String openid = openidAndRoomId;
            String roomId = openidAndRoomId;
            String avatar = "https://p11.douyinpic.com/aweme/100x100/aweme-avatar/tos-cn-i-0813_oAAiAbeXnAAleAqAksDIC4EWLCCISGdgGT9ZFA.jpeg?from=3067671334";
            String nickName = "测试号[" + openidAndRoomId + "]";
            return this.loginByCode(openid, roomId, avatar, nickName);
        }


        JSONObject roomInfo = douYinApiService.getRoomInfo(token).getJSONObject("info");
        String openid = roomInfo.getString("anchor_open_id");
        String roomId = roomInfo.getString("room_id");
        String avatar = roomInfo.getString("avatar_url");
        String nickName = roomInfo.getString("nick_name");
        return this.loginByCode(openid, roomId, avatar, nickName);
    }



    /**
     * Authenticates the user. If something is wrong, an {@link AuthenticationException} will be thrown
     *
     * @return Authentication
     */
    private Authentication authenticate(String username, String password) {
        Objects.requireNonNull(username);
        Objects.requireNonNull(password);
        try {
            //user实现类为jwtUserDetailsService 密码效验为WebSecurityConfigurerAdapter 的 matches方法
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException e) {
            throw new AuthenticationException("禁止登录", e);
        } catch (BadCredentialsException e) {
            throw new AuthenticationException("用户名或密码错误", e);
        }
    }


    @PostMapping("/logs")
    @ApiOperation("错误日志")
    @ApiImplicitParams({
            @ApiImplicitParam(name="logs", value="错误日志"),
    })
    public BusiResult<?> logs(@RequestParam  String logs){
        log.info("前端错误信息:{}, ", logs);
        return BusiResult.success( );
    }


}
